package com.sc.nft.controller;

import com.sc.nft.annotation.UserLogin;
import com.sc.nft.controller.request.*;
import com.sc.nft.dto.MallOrderRefundDTO;
import com.sc.nft.entity.vo.mall.*;
import com.sc.nft.enums.RedisKeyEnum;
import com.sc.nft.exception.GlobalException;
import com.sc.nft.pool.UserPool;
import com.sc.nft.service.MallOrderRefundService;
import com.sc.nft.service.MallOrderService;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.sup.PageRequest;
import com.sc.nft.sup.PageResult;
import com.sc.nft.sup.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.concurrent.TimeUnit;

/**
 * 服务控制器
 *
 * @author 张翔宇
 * @since 2022-06-02 01:07:23
 */
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/ipMall/order")
@Api(tags = "IP商城订单")
public class IPMallOrderController {


    private final MallOrderService mallOrderService;
    private final Redisson redisson;

    @ApiOperation(value = "商品计价", notes = "商品计价", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/productValuation", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<ProductValuationVO> productValuation(@Valid @RequestBody OrderConfirmRequest request) throws GlobalException {
        return Result.success(mallOrderService.productValuation(request.getActivityId(), request.getSpecsId(), request.getCount(), UserPool.getUser(), request.getShareTeamId()));
    }

    @ApiOperation(value = "IP商城订单确认(生成订单前调用)", notes = "订单确认(生成订单前调用)", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/orderConfirm", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<OrderConfirmVO> orderConfirm(@Valid @RequestBody OrderConfirmRequest request) throws GlobalException {
        return Result.success(mallOrderService.orderConfirm(request.getActivityId(), request.getSpecsId(), request.getCount(), UserPool.getUser(), request.getShareTeamId(),request.getGroupId()));
    }

    @ApiOperation(value = "IP商城订单确认(生成订单后调用)", notes = "订单确认(生成订单后调用)", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/orderConfirmByOrderNo", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<OrderConfirmByOrderNoVO> orderConfirmByOrderNo(@Valid @RequestBody OrderConfirmByOrderIdRequest request) throws GlobalException {
        return Result.success(mallOrderService.orderConfirmByOrderId(request.getOrderNo()));
    }


    @ApiOperation(value = "创建IP商城订单", notes = "创建ip商城订单", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/createMallOrder", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<CreateMallOrderVO> createMallOrder(@Valid @RequestBody CreateMallOrderRequest request) throws GlobalException {
        CreateMallOrderVO order = null;
        RLock lock = redisson.getLock(RedisKeyEnum.IP_PRODUCT_STOCK_LOCK.getKey() + request.getActivityId());
        try {
            boolean res = lock.tryLock(3, 10, TimeUnit.SECONDS);
            if (res) {
                order = mallOrderService.createMallOrder(request.getActivityId(), request.getSpecsId(), request.getCount(), UserPool.getUser(), request.getMallDeliveryAddressId(), request.getDealPwd(), request.getApiChargeAccount(), request.getUserCouponsId(), request.getShareTeamId(),request.getGroupId());
            }else {
                return Result.fail(ErrorCode.LATER_TRY);
            }
        } catch (InterruptedException e) {
            return Result.fail("当前人数过多，请稍后再试");
        } finally {
            lock.unlock();
        }
        return Result.success(order);
    }


    @ApiOperation(value = "IP商城订单列表(购买订单/兑换订单)", notes = "IP商城订单列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/pageMallOrder", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public PageResult<PageMallOrderVO> pageMallOrder(@Valid @RequestBody PageMallOrderRequest request) throws GlobalException {
        return PageResult.success(mallOrderService.pageMallOrder(UserPool.getUserId(), request.getActivityType(), request.getQueryStatus(), request.getPageNo(), request.getPageSize(),UserPool.getSource(),UserPool.getWxMiniUserId()));
    }

    @ApiOperation(value = "IP商城订单详情(购买订单/兑换订单)", notes = "IP商城订单列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/mallOrderDetails", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<MallOrderDetailsVO> mallOrderDetails(@Valid @RequestBody MallOrderDetailsRequest request) throws GlobalException {
        return Result.success(mallOrderService.mallOrderDetails(UserPool.getUserId(), request.getId(), UserPool.getSource(), UserPool.getWxMiniUserId()));
    }


    @ApiOperation(value = "IP商城-推广订单列表", notes = "IP商城-推广订单", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/pageMallPopularizeOrder", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public PageResult<PageMallPopularizeOrderVO> pageMallPopularizeOrder(@Valid @RequestBody PageMallPopularizeOrderRequest request) throws GlobalException {
        return PageResult.success(mallOrderService.pageMallPopularizeOrder(UserPool.getUser(), request.getIncomeStatus(), request.getPageNo(), request.getPageSize()));
    }

    @ApiOperation(value = "手动关闭订单(取消订单)", notes = "手动关闭订单(取消订单)", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/cancelOrderById", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result cancelOrderById(@Valid @RequestBody IdRequest request) throws GlobalException {
        mallOrderService.cancelOrderById(request.getId(), UserPool.getUserId(),UserPool.getSource(), UserPool.getWxMiniUserId());
        return PageResult.success();
    }

    @ApiOperation(value = "手动确认收货(确认收货)", notes = "手动确认收货(确认收货)", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/confirmOrderById", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result confirmOrderById(@Valid @RequestBody IdRequest request) throws GlobalException {
        mallOrderService.confirmOrderById(request.getId(), UserPool.getUserId(),UserPool.getSource(), UserPool.getWxMiniUserId());
        return PageResult.success();
    }


    @ApiOperation(value = "更换收货地址", notes = "更换收货地址", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/updateMallDeliveryAddress", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<UpdateMallDeliveryAddressVO> updateMallDeliveryAddress(@Valid @RequestBody UpdateMallDeliveryAddressRequest updateMallDeliveryAddressRequest) throws GlobalException {
        return PageResult.success(mallOrderService.updateMallDeliveryAddress(updateMallDeliveryAddressRequest.getId(),updateMallDeliveryAddressRequest.getMallDeliveryAddressId(), UserPool.getUserId(),UserPool.getSource(), UserPool.getWxMiniUserId()));
    }


    @ApiOperation(value = "获取当前订单地址", notes = "获取当前订单地址", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/orderNowAddress", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<MallOrderDeliveryAddressVO> orderNowAddress(@Valid @RequestBody IdRequest idRequest) throws GlobalException {
        return PageResult.success(mallOrderService.orderNowAddress(idRequest.getId(),UserPool.getUserId(),UserPool.getSource(), UserPool.getWxMiniUserId()));
    }


}